package com.gitee.baqkft.code.ui.dlg;

import com.gitee.baqkft.code.ui.component.JavaModelConfigPanel;
import com.gitee.baqkft.code.ui.component.TableConfigPanel;
import com.gitee.baqkft.code.ui.layout.GBC;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.*;
import org.mybatis.generator.internal.DefaultShellCallback;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;

/**
 * mybatis代码生成窗口
 * @Author: chenmingcai
 * @Date 2020/5/30 1:19 下午
 **/

public class MybatisGeneratorFrame extends JFrame
{
    /**
     * Java配置
     */
    private final JavaModelConfigPanel modelConfigPanel;

    /**
     * Mapper配置
     */
    private final JavaModelConfigPanel mapperConfigPanel;

    /**
     * Java Client配置
     */
    private final JavaModelConfigPanel clientConfigPanel;

    /**
     * 数据表配置
     */
    private final TableConfigPanel tableConfigPanel;

    /**
     * 信息显示数据
     */
    private final DefaultListModel<String> listModel;

    /**
     * 数据连接配置
     */
    private final JDBCConnectionConfiguration connectionConfiguration;

    /**
     * 数据表名
     */
    private final String tableName;

    public MybatisGeneratorFrame(JDBCConnectionConfiguration connectionConfiguration,
                                 String tableName)
    {
        this.connectionConfiguration = connectionConfiguration;
        this.tableName = tableName;
        listModel = new DefaultListModel<>();

        setLayout(new GridBagLayout());
        modelConfigPanel = new JavaModelConfigPanel();
        GBC gbc = new GBC(0, 0, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        modelConfigPanel.setBorder(BorderFactory.createTitledBorder("JavaBean配置"));
        add(modelConfigPanel, gbc);

        mapperConfigPanel = new JavaModelConfigPanel();
        gbc = new GBC(0, 1, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        mapperConfigPanel.setBorder(BorderFactory.createTitledBorder("Mapper配置"));
        add(mapperConfigPanel, gbc);

        clientConfigPanel = new JavaModelConfigPanel();
        gbc = new GBC(0, 2, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        clientConfigPanel.setBorder(BorderFactory.createTitledBorder("Client配置"));
        add(clientConfigPanel, gbc);

        tableConfigPanel = new TableConfigPanel(tableName);
        gbc = new GBC(0, 3, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        tableConfigPanel.setBorder(BorderFactory.createTitledBorder("表映射配置"));
        add(tableConfigPanel, gbc);

        JPanel buttonPanel = createOperatePanel();
        gbc = new GBC(0, 4, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        add(buttonPanel, gbc);

        JList messages = new JList(listModel);
        gbc = new GBC(0, 5, 1, 1);
        gbc.setWeight(1, 1).setFill(GBC.BOTH);
        add(new JScrollPane(messages), gbc);

        setSize(800, 600);
    }

    /**
     * 创建按钮操作
     * @return
     */
    private JPanel createOperatePanel()
    {
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        JPanel space1 = new JPanel();
        GBC gbc = new GBC(0, 0, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        panel.add(space1, gbc);

        JButton btnGenerate = new JButton("生成");
        gbc = new GBC(1, 0, 1,1);
        gbc.setWeight(0, 0);
        panel.add(btnGenerate, gbc);

        JPanel space2 = new JPanel();
        gbc = new GBC(2, 0, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        panel.add(space2, gbc);

        btnGenerate.addActionListener(this::generate);

        return panel;
    }

    /**
     * 生成代码
     * @throws Exception
     */
    public void generate(ActionEvent event)
    {
        Configuration config = new Configuration();
        Context context = new Context(ModelType.FLAT);
        context.setId("MySQLContext");
        context.setTargetRuntime("MyBatis3");
        config.addContext(context);

        //paging
        PluginConfiguration rowBounds = new PluginConfiguration();
        rowBounds.setConfigurationType("org.mybatis.generator.plugins.RowBoundsPlugin");
        context.addPluginConfiguration(rowBounds);

        PluginConfiguration mapperAnnotation = new PluginConfiguration();
        mapperAnnotation.setConfigurationType("org.mybatis.generator.plugins.MapperAnnotationPlugin");
        context.addPluginConfiguration(mapperAnnotation);

        //覆盖xml mapper
        PluginConfiguration xmlMapper = new PluginConfiguration();
        xmlMapper.setConfigurationType("org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin");
        context.addPluginConfiguration(xmlMapper);

        //comment setting
        CommentGeneratorConfiguration commentCfg = new CommentGeneratorConfiguration();
        commentCfg.setConfigurationType("com.gitee.baqkft.code.mybatis.FriendlyCommentGenerator");
        commentCfg.addProperty("suppressAllComments", "true");
        commentCfg.addProperty("addRemarkComments", "true");
        context.setCommentGeneratorConfiguration(commentCfg);

        //java model setting
        JavaModelGeneratorConfiguration modelGenCfg = new JavaModelGeneratorConfiguration();
        modelGenCfg.setTargetPackage(modelConfigPanel.getTargetPackage());
        modelGenCfg.setTargetProject(modelConfigPanel.getTargetProject());
        modelGenCfg.addProperty("enableSubPackages", String.valueOf(modelConfigPanel.isEnableSubPackage()));
        context.setJavaModelGeneratorConfiguration(modelGenCfg);

        //sql mapper settings
        SqlMapGeneratorConfiguration sqlMapGenCfg = new SqlMapGeneratorConfiguration();
        sqlMapGenCfg.setTargetPackage(mapperConfigPanel.getTargetPackage());
        sqlMapGenCfg.setTargetProject(mapperConfigPanel.getTargetProject());
        sqlMapGenCfg.addProperty("enableSubPackages", String.valueOf(mapperConfigPanel.isEnableSubPackage()));
        context.setSqlMapGeneratorConfiguration(sqlMapGenCfg);

        JavaClientGeneratorConfiguration clientCfg = new JavaClientGeneratorConfiguration();
        clientCfg.setTargetPackage(clientConfigPanel.getTargetPackage());
        clientCfg.setTargetProject(clientConfigPanel.getTargetProject());
        clientCfg.setConfigurationType("XMLMAPPER");
        clientCfg.addProperty("enableSubPackages", String.valueOf(clientConfigPanel.isEnableSubPackage()));
        context.setJavaClientGeneratorConfiguration(clientCfg);
        context.setJava8Targeted(true);

        TableConfiguration tableConfiguration = new TableConfiguration(context);
        tableConfiguration.setTableName(tableConfigPanel.getTableName());
        tableConfiguration.setDomainObjectName(tableConfigPanel.getObjectName());
        tableConfiguration.setCountByExampleStatementEnabled(false);
        tableConfiguration.setUpdateByExampleStatementEnabled(false);
        tableConfiguration.setDeleteByExampleStatementEnabled(false);
        tableConfiguration.setSelectByExampleStatementEnabled(false);
        context.addTableConfiguration(tableConfiguration);

        //添加数据连接
        context.setJdbcConnectionConfiguration(connectionConfiguration);

        boolean overwrite = true;
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        ArrayList<String> warnings = new ArrayList<>();
        StringBuffer message = new StringBuffer();
        try
        {
            MyBatisGenerator generator = new MyBatisGenerator(config, callback, warnings);
            generator.generate(null);
            message.append(LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)).append(": success");
        }
        catch (Exception ex)
        {
            message.append(LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)).append(": ");
            message.append("生成失败, ").append(ex.getMessage());
        }
        listModel.add(0, message.toString());
    }
}
